//ओ३म् ( ॐ) ॥ श्री गणेशाय नमः ॥ जय श्री राम ॥ ॐ नमः शिवाय
#include <bits/stdc++.h>
#include <iostream>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define pb(n) push_back(n)
#define all(v) v.begin(),v.end()
#define rall(v) v.rbegin(),v.rend()
#define coutyes cout<<"YES"<<endl
#define coutno cout<<"NO"<<endl
#define mp make_pair
#define ff first
#define ss second
#define rep(i, n) for(int i=0;i<n;i++)
#define vep(i, j, n) for(int i=j;i<n;i++)
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL)
using namespace std;
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
typedef tree<pair<int, int>, null_type,
less<pair<int, int>>, rb_tree_tag,
tree_order_statistics_node_update>
ordered_set_pair;
// order_of_key (k) : Number of items strictly smaller than k.
// find_by_order(k) : K-th element in a set (counting from zero).
typedef long long ll;
typedef long double ld;
ll N = 1000000007;
void init_code() {
fast_io;
#ifndef ONLINE_JUDGE
freopen("Input1.txt", "r", stdin);
freopen("Output1.txt", "w", stdout);
#endif
}
//2d prefix{
//to cal prefix ->pre[i][j]= v[i][j]+pre[i][j-1]+pre[i-1][j]-pre[i-1][j-1];
//to get ans from a,b->c,d ->pre[c][d]-pre[a-1][d]-pre[c][b-1]+pre[a-1][b-1];
//}
ll powe(ll a, ll n) {
ll r = 1;
while (n) {
if (n % 2) {
r = ((r % N) * (a % N)) % N;
n--;
}
else {
a = ((a % N) * (a % N)) % N;
n = n / 2;
}
}
return r;
}
int M = 1000000;
int sieve[1000001];
void createSieve() {
for (int i = 2; i <= M; i++) {
sieve[i] = 1;
}
for (int i = 2; i * i <= M; i++) {
if (sieve[i] == 1) {
if (i == 2) {
for (int j = i * i; j <= M; j += i) {
sieve[j] = 2;
}
}
else {
for (int j = i * i; j <= M; j += 2 * i) {
if (sieve[j] == 1) {
sieve[j] = i;
}
}
}
}
}
}
// <-------------------KMP Algo for pattern searching------------------>
// For KMP call MAtch() function.
vector<int> KMP(string& s) {
int n = s.size();
vector<int> lps(n);
lps[0] = 0;
for (int i = 1, j = 0; i < n; ++i) {
while (j > 0 && s[i] != s[j])
j = lps[j - 1];
if (s[i] == s[j])
++j;
lps[i] = j;
}
return lps;
}
vector<int> Match(string& s, string& t) {
int n = s.size();
auto lps = KMP(s);
int m = t.size();
vector<int> pos;
for (int i = 0, j = 0; i < m; ++i) {
while (j == n || (j > 0 && t[i] != s[j]))
j = lps[j - 1];
if (s[j] == t[i])
++j;
if (j == n) {
pos.push_back(i - n + 1);
}
}
return pos;
}
// <-------------------------------------------------------->
// <--------4 term recurrence for Triangle of Mahonian numbers------->
// (A):f(n,k)=f(n−1,k)+f(n−1,k−1)+f(n−1,k−2)+⋯+f(n−1,k−n+1)
// (B):f(n,k−1)=f(n−1,k−1)+f(n−1,k−2)+f(n−1,k−3)+⋯+f(n−1,k−n+1)+f(n−1,k−n)
// (A)-(B) follows:
// IMPORTANT:
// ⟹f(n,k)=f(n−1,k)+f(n,k−1)−f(n−1,k−n)
// <----------------------------------------------------------------------------------->
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
class DisjointSet {
vector<ll> rank, parent, size;
public:
DisjointSet(ll n) {
rank.resize(n + 1, 0);
parent.resize(n + 1);
size.resize(n + 1);
for (int i = 0; i <= n; i++) {
parent[i] = i; size[i] = 1;
}
}
int findUpar(int node) {
if (node == parent[node])return node;
return parent[node] = findUpar(parent[node]);
}
void unionByRank(int u, int v) {
int up_u = findUpar(u);
int up_v = findUpar(v);
if (up_u == up_v)return;
if (rank[up_u] < rank[up_v]) {
parent[up_u] = up_v;
}
else if (rank[up_v] < rank[up_u]) {
parent[up_v] = up_u;
}
else {
parent[up_v] = up_u;
rank[up_u]++;
}
}
void unionBySize(int u, int v) {
int up_u = findUpar(u);
int up_v = findUpar(v);
if (up_u == up_v)return;
if (size[up_u] < size[up_v]) {
parent[up_u] = up_v;
size[up_v] += size[up_u];
}
else {
parent[up_v] = up_u;
size[up_u] += size[up_v];
}
}
};
// Binary Lifting to find Kth ancestor
ll up[200010][25];
vector<ll> depth(200010);
void binary_lifting(ll src, ll par, vector<vector<ll>> &adj)
{
up[src][0] = par;
for (int i = 1; i < 22; i++)
{
if (par != -1)depth[src] = depth[par] + 1;
if (up[src][i - 1] != -1)
up[src][i] = up[up[src][i - 1]][i - 1];
else up[src][i] = -1;
}
for (int child : adj[src])
{
if (child != par && child != src)
binary_lifting(child, src, adj);
}
}
ll getKthAncestor(ll node, ll k) {
if (depth[node] < k) {
return -1;
}
for (int j = 20; j >= 0; j--) {
if (k >= (1 << j)) {
node = up[node][j];
k -= 1 << j;
}
}
return node;
}
void solve() {
ll n, k, ans = 0; cin >> n >> k;
vector<vector<ll>> adj(n + 1);
map<pair<ll, ll>, vector<ll>> mp;
rep(i, k) {
ll m; cin >> m;
rep(j, m) {
ll u, v; cin >> u >> v;
adj[u].pb(v); adj[v].pb(u);
mp[ {u, v}].pb(i + 1);
mp[ {v, u}].pb(i + 1);
}
}
ll t; cin >> t; vector<ll> a(t);
vector<vector<ll>> tt(k + 1);
rep(i, t) {
cin >> a[i];
tt[a[i]].pb(i + 1);
}
vector<ll> dis(n + 1, 1e18), vis(n + 1);
priority_queue<pair<ll, ll>> pq;
pq.push({0, 1}); dis[1] = 0;
while (!pq.empty()) {
auto it = pq.top(); pq.pop();
ll d = -1 * it.first, nd = it.second;
if (vis[nd] == 1)continue;
vis[nd] = 1;
for (auto j : adj[nd]) {
if (vis[j] == 0) {
ll mn = 1e18;
for (auto i : mp[ {nd, j}]) {
ll jj = upper_bound(all(tt[i]), d) - tt[i].begin();
if (jj != tt[i].size()) {
jj = tt[i][jj];
mn = min(mn, jj);
}
}
if (dis[j] > mn) {
dis[j] = mn;
pq.push({ -mn, j});
}
}
}
}
ans = dis[n];
if (ans == 1e18)ans = -1;
cout << ans << endl;
}
int main() {
init_code();
ll t;
t = 1;
// cin >> t;
while (t--) {
solve();
}
return 0;
}
566. Reshape the Matrix | 167. Two Sum II - Input array is sorted |
387. First Unique Character in a String | 383. Ransom Note |
242. Valid Anagram | 141. Linked List Cycle |
21. Merge Two Sorted Lists | 203. Remove Linked List Elements |
733. Flood Fill | 206. Reverse Linked List |
83. Remove Duplicates from Sorted List | 116. Populating Next Right Pointers in Each Node |
145. Binary Tree Postorder Traversal | 94. Binary Tree Inorder Traversal |
101. Symmetric Tree | 77. Combinations |
46. Permutations | 226. Invert Binary Tree |
112. Path Sum | 1556A - A Variety of Operations |
136. Single Number | 169. Majority Element |
119. Pascal's Triangle II | 409. Longest Palindrome |
1574A - Regular Bracket Sequences | 1574B - Combinatorics Homework |
1567A - Domino Disaster | 1593A - Elections |
1607A - Linear Keyboard | EQUALCOIN Equal Coins |